home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
PD126.ARJ
/
PD.C
next >
Wrap
Text File
|
1992-03-08
|
7KB
|
276 lines
/********************************************************************
PopDATE - RESIDENT CODE & DATA
(c) Copyright 1992 by Omega Point, Inc.
Author: Ratko V. Tomic
*********************************************************************/
#include "cr.h"
/********************************************************************
Definitions/Utilities used by the TSR
*********************************************************************/
#define GREG_YEAR 1582 /* Gregorian calendar from Fri, Oct 15, 1582 */
#define GREG_MON 10 /* Julian calendar was valid earlier */
#define GREG_DAY 15
#define MAX_YEAR 32000
int x0=8,y0=14; /* Upper Left corner for calendar */
int wdx,wdy; /* Window sizes */
int mx,my; /* Coordinates for day of month numbers */
int rvx,rvy; /* Saved coordinates for last highlight */
int col; /* Column for days of month */
word *buf; /* Buffer with calendar image/save image */
char str[4]="25"; /* Used for conversions of numbers */
#define lead0 str[3] /* Last byte of str[]=flag for leading 0 */
/* 0 1 2 3 4 5 */
byte cal_atr[6]={0x13,0x1B,0x71,0x74,0x4E,0x7C};
#define atr_low cal_atr[0]
#define atr_high cal_atr[1]
#define atr_bord cal_atr[2]
#define atr_arrow cal_atr[3]
#define atr_rev cal_atr[4]
#define atr_dw cal_atr[5]
/*** Set X,Y to upper left corner ***/
corner()
{
crs_x=x0; crs_y=y0;
}
bottom()
{
crs_x=x0+4; crs_y=y0+wdy-1;
vid_atr=atr_bord;
}
/*** Swap screen image from buffer with Video RAM image ***/
/*** This is an efficient way to save and restore screen ***/
swap_screen()
{
corner();
swap_blk(wdx,wdy,buf);
}
/*** DISPLAY 2 DIGIT NUMBER ***/
show_num(int Num)
{ char *s=str;
int w;
*s=(w=Num)/10;
s[1]=w%10;
*(word*)s|=0x3030; /* Convert to ASCII */
if (!lead0 && w<10) *s=0x20; /* Remove leading 0 */
dsp(s); crs_x++;
}
/*** DISPLAY LIST OF NUMBERS, WRAP INSIDE CALENDAR BOX ***/
show_lst(int Start,int Cnt)
{ int n,c;
n=Start; c=Cnt;
vid_atr=atr_high; /* Set-up high/low attributes */
if (c<15)
vid_atr=atr_low;
do {
show_num(n++);
crs_x++;
if (++col==7) /* Wrap around after 7th day */
{
col=0;
crs_y++; crs_x=mx;
}
}
while(--c);
}
show_time(TIME_REC *Time)
{ char *t;
int am;
bottom(); crs_x+=15;
t=&Time->hours;
am='A';
if (*t>12)
{
*t-=12; am='P';
}
if (!*t) {*t=12; am='P';}
lead0=0;
do {
show_num(*t);
lead0=1;
}
while(--t>(char*)Time);
dsp(&am);
}
/***************************************************************
CALENDAR COMPUTATIONS & DISPLAY
****************************************************************/
char mstr[12*4]= "Jan\x0" "Feb\x0" "Mar\x0" "Apr\x0" "May\x0"
"Jun\x0" "Jul\x0" "Aug\x0" "Sep\x0" "Oct\x0"
"Nov\x0" "Dec\x0";
char mlen[13]= {31,31,28,31,30,31,30,31,31,30,31,30,31};
/******************************************
Set length of February
*******************************************/
void set_feb(word Year)
{ word y=Year;
char *m=mlen+2;
*m=28; /* Assume non-leap year */
if (y&3) return; /* Not div by 4 - regular */
(*m)++; /* Div by 4 - assume leap */
if (!(y%100) && y%400) /* Except when div by 100 */
(*m)--; /* but not if div by 400 */
}
/******************************************************
Compute day of week (Mon=0,Tue=1,..Sun=6)
*******************************************************/
int day_of_week(DATE_REC *d)
{ int i;
word y,w;
set_feb(y=d->year);
w=(y+y/4-y/100+y/400);
i=0; y=d->month;
while (++i<y)
w+=mlen[i];
return (w+d->day_of_month+5-(mlen[2]&1))%7;
}
/*********************************************
DISPLAY CALENDAR
**********************************************/
void show_cal(TD_REC *d)
{ int m,d1,dw,c;
crs_x=rvx; crs_y=rvy; /* Remove earlier highlight */
vid_atr=atr_high;
hor_atr(4);
lead0=col=0; /* No leading 0 for days in month */
crs_x=mx; crs_y=my;
dw=day_of_week((DATE_REC*)&d->day);
d1=(dw+36-d->day)%7; /* 1st day of this month */
if (!d1) d1=7;
m=d->mon;
show_lst(mlen[m-1]-(d1-1),d1); /* Show previous month, few days */
show_lst(1,c=mlen[m]); /* Show current month */
show_lst(1,42-(c+d1)); /* Show next month, few days */
bottom(); /* Display line at the bottom */
dsp(mstr+m*4-4); /* Display current month */
crs_x++;
show_num(d->day); /* Display day of month */
lead0++; crs_x++;
show_num(d->year/100); /* Display year */
crs_x--;
show_num(d->year%100);
corner();
hor_atr(wdx); /* Remove old day-of-week highlight */
rvx=(crs_x+=2+(dw<<=2));
vid_atr=atr_arrow;
hor_atr(4); /* Highlight current day-of-week */
vid_atr=atr_rev; /* Reverse video on day of month */
rvy=(crs_y+=1+(d->day+d1-1)/7);
hor_atr(4); /* Show day of month */
}
/**************************************************************
MAIN CONTROL LOOP
***************************************************************/
run_calendar()
{ TD_REC td;
int cy,sy; /* Current year, selected year, prev year */
char cm,sm; /* Current month, selected month, prev month */
char cd;
cd=cm=sm=cy=sy=0;
while(1)
{
Redo:
dos_td(&td);
show_time((TIME_REC*)&td);
if (cy==sy && cm==sm) /* Displaying cy,cm month */
{
if (td.year!=cy || td.mon!=cm || td.day!=cd)
{
cy=sy=td.year;
cm=sm=td.mon;
cd=td.day;
show_cal(&td);
}
}
if (!anykey()) continue;
switch (pckey())
{
default: cy=sy; cm=sm; cd=0;
goto Redo;
case K_LEFT: if (sm>1) {sm--; break;}
sm=12;
case K_UP: sy--; break;
case K_RIGHT: if (sm<12) {sm++; break;}
sm=1;
case K_DN: sy++; break;
case K_PGUP: sy-=10; break;
case K_PGDN: sy+=10; break;
case 0x1B: ;
case K_ESC: goto Done;
}
td.day=1;
if (sy>=MAX_YEAR) sy=MAX_YEAR;
if (sy<=GREG_YEAR)
{
sy=GREG_YEAR;
if (sm<=GREG_MON)
{
sm=GREG_MON;
td.day=GREG_DAY;
}
}
td.year=sy; td.mon=sm;
cd=0;
show_cal(&td);
}
Done:
flush_kbd();
}
/***************************************************************
HOTKEY SERVICE
***************************************************************/
void service()
{
if (dos_busy(20)) /* We need DOS for current date time */
return;
chk_video();
swap_screen();
_hkey_again=0;
run_calendar();
swap_screen();
}